//
//  GroupDelegate.m
//  TcpTest_Server
//
//  Created by arvintan on 12-7-28.
//  Copyright (c) 2012年 tencent. All rights reserved.
//

#import "GroupPacketCenter.h"
#import "MainSocketDelegate.h"
#import "MacroComd.h"
#import "SockPacket.h"
#import "MiniSocket.h"
#import "MysqlDB.h"

@implementation GroupPacketCenter

-(NSData*) dataCmd:(NSData *)data cmd:(NSUInteger)cmdFlag subcmd:(NSUInteger)subCmdFlag
{
    NSUInteger length = data.length + 16;
    NSLog(@"data length is %lu,%lu",data.length,sizeof(NSUInteger));
    NSMutableData *dataWithCmd = [NSMutableData dataWithBytes:&(length) length:sizeof(NSUInteger)];
    [dataWithCmd appendBytes:&(cmdFlag) length:sizeof(NSUInteger)];
    [dataWithCmd appendBytes:&(subCmdFlag) length:sizeof(NSUInteger)];
    [dataWithCmd appendData:data];
    
    return dataWithCmd;
}


-(void)MessageDispatch: (SockPacket *)packet
{
    void* bytes = (void *)[packet.packetContent bytes] + 8;
    NSUInteger subFun =*((NSUInteger *) bytes);  
    switch (subFun) 
    {
        case CMD_GROUP_CREATE_REQUEST:
            [self groupCreateRequest:(bytes+8) Socket:packet];
            break;
        case CMD_GROUP_LIST_REQUEST:
            [self groupListRequest:(bytes+8) Socket:packet];
            break;            
        case CMD_GROUP_MEMBERLIST_REQUEST:
            [self groupMemberListRequest:(bytes+8) Socket:packet];
            break;            
        case CMD_GROUP_EXIT_REQUEST:
            [self groupExitRequest:(bytes+8) Socket:packet];
            break;
        default:
        {
            NSString *msg = [[NSString alloc] initWithBytes:(bytes+8)
                                                      length:(packet.packetLen-16) encoding:NSUTF8StringEncoding];
            if(msg)
            {
                NSLog(@"log delegate message--->收到---%@ subfun is %lu\r\n",msg,subFun);
                NSUInteger length = packet.packetLen;
                NSMutableData *data = [NSMutableData dataWithBytes:&(length) length:sizeof(NSUInteger)];
                [data appendBytes:[packet.packetContent bytes] length:length];
                /*dispatch_async(dispatch_get_main_queue(), ^{ 
                    [packet.subAsynSocket writeData:data withTimeout:-1 tag:0];
                });*/
                [packet.subAsynSocket writeData:data withTimeout:-1 tag:0];
            }
            else
            {
                NSLog(@"Error converting received data into UTF-8 String");
            }
            break;
            
        }
    }
    
}

-(void) groupExitRequest:(void*) request Socket:(SockPacket*) packet
{
    NSUInteger groupId = *((NSUInteger*)request);
    NSUInteger userId = *((NSUInteger*)(request+8));
    
    //建立数据库连接
    MysqlDB *mysql = [[MysqlDB alloc] init];
    [mysql connectHost:hostIp connectUser:userName connectPassword:password connectName:dbName];
    
    NSString *sqlCluster = [NSString stringWithFormat:@"select MemberId from tbGroupMember where GroupId = %ld",groupId];
    NSMutableArray *memberIDResult = [mysql doDataQuery:sqlCluster];
    NSString *sqlDelete = [NSString stringWithFormat:@"delete from tbGroupMember where GroupId = %ld && memberId = %ld",groupId,userId];
    [mysql doDataDelete:sqlDelete];
    NSUInteger count = [memberIDResult count];
    NSUInteger result = 0;
    if (count <= 1) {
        NSString *sqlDeleteGroup = [NSString stringWithFormat:@"delete from tbGroup where groupId = %ld",groupId];    
         result =  [mysql doDataDelete:sqlDeleteGroup];        
    }
    else {
        NSString *sqlUpdate = [NSString stringWithFormat:@"update tbGroup set groupNum='%ld' where groupId = %ld",count-1,groupId]; 
        result = [mysql doDataUpdate:sqlUpdate];
    }
    
    if (result) {
        NSLog(@"SQL error in groupExitRequest");
        return;
    }
    
    
    NSData *replyData = [[NSData alloc] initWithBytes:request length:2*sizeof(NSUInteger)];
    NSData *replyDataWithCmd = [self dataCmd:replyData cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_EXIT_REPLY];
    
    for (NSUInteger i = 0; i < [memberIDResult count]; ++i) 
    {
        NSArray *temp = [memberIDResult objectAtIndex:i];
        NSUInteger memberId = [[temp objectAtIndex:0] integerValue];
        if (memberId != userId) 
        {
            @synchronized([MainSocketDelegate connectedSocketsQueue])
            {
                MiniSocket *_sock = [self isBuddyOnline:memberId];   // 判断该好友是否在线
                if (_sock != nil)
                {
                    [_sock.miniAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0];
                }
            }
        }
    }
    
    [mysql disconnect];
}

-(void) groupMemberListRequest:(void*)request Socket:(SockPacket*) packet
{
    NSUInteger clusterID = *((NSUInteger*)request);
    
    //建立数据库连接
    MysqlDB *mysql = [[MysqlDB alloc] init];
    [mysql connectHost:hostIp connectUser:userName connectPassword:password connectName:dbName];
    
    NSString *sqlCluster = [NSString stringWithFormat:@"select MemberId from tbGroupMember where GroupId = %ld",clusterID];
    NSMutableArray *memberIDResult = [mysql doDataQuery:sqlCluster];
     
    NSInteger isError = GROUP_MEMBERLIST_NO_ERROR;
    
    NSMutableArray *memberIDArray = [[NSMutableArray alloc] init];
    NSMutableArray *memberNameArray = [[NSMutableArray alloc] init];
    NSMutableArray *memberImageArray = [[NSMutableArray alloc] init];
    NSMutableArray *memberStatusArray = [[NSMutableArray alloc] init];
    NSMutableArray *memberListenPortArray = [[NSMutableArray alloc] init];
    NSMutableArray *memberIpArray = [[NSMutableArray alloc] init];
    
    if ([memberIDResult count] == 0)
    {
        isError = GROUP_MEMBERLIST_SQL_ERROR;
    }
    else 
    {
        // 查询 tbUser 表
        for (NSInteger i=0; i<[memberIDResult count]; ++i)
        {            
            NSArray *temp = [memberIDResult objectAtIndex:i];
            NSString *buddyId = [temp objectAtIndex:0];
            [memberIDArray addObject:buddyId];
            
            NSString *sqlBuddyInfo = [NSString stringWithFormat:@"select * from tbUser where UserId = %@",buddyId];
            
            NSMutableArray *buddyUser = [mysql doDataQuery:sqlBuddyInfo];
            if ([buddyUser count] != 1) // 查无此人，或者这个 id 有多个记录(不可能，除非数据库出错)
            {
                isError = GROUP_MEMBERLIST_SQL_ERROR;
                break;
            }
            NSArray *buddyUserInfo = [buddyUser objectAtIndex:0];

            NSString *buddyName = [buddyUserInfo objectAtIndex:COLUMN_OF_USERNAME];  // 取出记录的第二列
            [memberNameArray addObject:buddyName];

            NSString *buddyUserImage =  [buddyUserInfo objectAtIndex:COLUMN_OF_USERIMAGE];
            [memberImageArray addObject:buddyUserImage];
            
            NSNumber *status;
            MiniSocket *sock = [self isBuddyOnline:[buddyId intValue]];
            if (sock == nil)   // 好友是否在线
            {
                status = [[NSNumber alloc] initWithInt:BUDDY_STATUS_OFFLINE];
                [memberStatusArray addObject:status];
                
                NSNumber *listenPort = [[NSNumber alloc] initWithInt:0];
                [memberListenPortArray addObject:listenPort];
                
                NSData *ipData = [[NSData alloc] init];
                [memberIpArray addObject:ipData];
            }
            else
            {
                status = [[NSNumber alloc] initWithInt:BUDDY_STATUS_ONLINE];
                [memberStatusArray addObject:status];
                
                NSNumber *listenPort = [[NSNumber alloc] initWithInt:(int)sock.listenPort];
                [memberListenPortArray addObject:listenPort];
                
                NSString *ipStr = [sock.miniAsynSocket connectedHost];
                [memberIpArray addObject:ipStr];
            }
        }
    }

    NSData *memberIDData = [NSKeyedArchiver archivedDataWithRootObject:memberIDArray];
    NSData *memberNameData = [NSKeyedArchiver archivedDataWithRootObject:memberNameArray];
    NSData *memberImageData = [NSKeyedArchiver archivedDataWithRootObject:memberImageArray];
    NSData *memberStatusData = [NSKeyedArchiver archivedDataWithRootObject:memberStatusArray];
    NSData *memberListenPortData = [NSKeyedArchiver archivedDataWithRootObject:memberListenPortArray];
    NSData *memberIpData = [NSKeyedArchiver archivedDataWithRootObject:memberIpArray];

    NSUInteger groupID = clusterID;
    CLUSTERMEMBERLISTREPLYHRD *replyHrd = malloc(sizeof(CLUSTERMEMBERLISTREPLYHRD));
    replyHrd->error = isError;
    replyHrd->count = [memberIDResult count];
    replyHrd->memberIDLen = [memberIDData length];
    replyHrd->memberNameLen = [memberNameData length];
    replyHrd->memberImageLen = [memberImageData length];
    replyHrd->memberStatusLen = [memberStatusData length];
    replyHrd->memberListenPortLen = [memberListenPortData length];
    replyHrd->memberIpLen = [memberIpData length];
    
    NSMutableData *data =[[NSMutableData alloc] initWithBytes:&groupID length:sizeof(NSUInteger)];
    [data appendBytes:replyHrd length:sizeof(CLUSTERMEMBERLISTREPLYHRD)];
    [data appendData:memberIDData];
    [data appendData:memberNameData];
    [data appendData:memberImageData];
    [data appendData:memberStatusData];
    [data appendData:memberListenPortData];
    [data appendData:memberIpData];
    
    
    NSData *dataWithCmd = [self dataCmd:data cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_MEMBERLIST_REPLY];
    [packet.subAsynSocket writeData:dataWithCmd withTimeout:-1 tag:0];
    
    //断开数据库连接
    [mysql disconnect];
}



-(void) groupListRequest:(void*) request Socket:(SockPacket*)packet
{
    //获取用户的userID
    NSUInteger userID = *((NSUInteger*)request);
    
    //建立数据库连接
    MysqlDB *mysql = [[MysqlDB alloc] init];
    [mysql connectHost:hostIp connectUser:userName connectPassword:password connectName:dbName];
    
    //新建需要发送的数据
    NSMutableArray *groupIDArray = [[NSMutableArray alloc] init];
    NSMutableArray *groupNameArray = [[NSMutableArray alloc] init];
    NSMutableArray *groupImageArray = [[NSMutableArray alloc] init];
    //[[NSString alloc] initWithData:[[NSData alloc] initWithBytes:request length:10] encoding:NSUTF8StringEncoding];
    //查找用户所在的组
    NSString *sqlCluster = [NSString stringWithFormat:@"select groupID from tbGroupMember where MemberId = %ld",userID];
    NSMutableArray *groupIDList = [mysql doDataQuery:sqlCluster];
    for( NSUInteger i = 0; i < [groupIDList count]; ++i)
    {
        NSArray *temp = [groupIDList objectAtIndex:i];
        NSString *groupID = [temp objectAtIndex:0];
        
        NSString *sqlGroupInfo = [NSString stringWithFormat:@"select * from tbGroup where groupID = %@",groupID];
        NSMutableArray *groupInfoList = [mysql doDataQuery:sqlGroupInfo];
        NSArray *groupInfo = [groupInfoList objectAtIndex:0];
        
        NSString *groupName = [groupInfo objectAtIndex:COLUMN_OF_GROUPNAME];
        NSString *groupImage = [groupInfo objectAtIndex:COLUMN_OF_GROUPIMAGE];
        [groupIDArray addObject:groupID];
        [groupNameArray addObject:groupName];
        [groupImageArray addObject:groupImage];
    }

    NSUInteger count = [groupIDList count];
    NSData *groupIDData = [NSKeyedArchiver archivedDataWithRootObject:groupIDArray];
    NSData *groupNameData = [NSKeyedArchiver archivedDataWithRootObject:groupNameArray];
    NSData *groupImageData = [NSKeyedArchiver archivedDataWithRootObject:groupImageArray];
    
    NSUInteger groupIdLen = [groupIDData length];
    NSUInteger groupNameLen = [groupNameData length];
    NSUInteger groupImageLen = [groupImageData length];

    
    CLUSTERLISTREPLYHRD *replyHrd = malloc(sizeof(CLUSTERLISTREPLYHRD));
    if(count != 0)
        replyHrd->error = GROUP_REQUEST_NO_ERROR;
    else {
        replyHrd->error = GROUP_REQUEST_SQL_ERROR;
    }
    replyHrd->count = count;
    replyHrd->groupIDLen = groupIdLen;
    replyHrd->groupNameLen = groupNameLen;
    replyHrd->groupImageLen = groupImageLen;
    
    NSMutableData *data = [[NSMutableData alloc] initWithBytes:replyHrd length:sizeof(CLUSTERLISTREPLYHRD)];
    [data appendData:groupIDData];
    [data appendData:groupNameData];
    [data appendData:groupImageData];
    NSData *dataWithCmd = [self dataCmd:data cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_LIST_REPLY];
    
    [mysql disconnect];
    [packet.subAsynSocket writeData:dataWithCmd withTimeout:-1 tag:0];
}

 
-(void) groupCreateRequest:(void *)request Socket:(SockPacket*)packet
{
    //解析创建包
    CLUSTERCREATEHRD *creatHrd = ((CLUSTERCREATEHRD *)request);
    NSUInteger userID = creatHrd->userID;
    NSUInteger count  = creatHrd->count;
    NSUInteger nameLen = creatHrd->nameLen;
    NSUInteger imageLen = creatHrd->headImageLen;

//    if (packet.packetLen != (sizeof(CLUSTERCREATEHRD)+nameLen+imageLen+16+count*8)) {
//        NSLog(@"Create Request Error ---- wrong data");
//        return;
//    }
    
    NSString *name = [[NSString alloc] initWithBytes:(request + sizeof(CLUSTERCREATEHRD)) length:nameLen encoding:NSUTF8StringEncoding];
    NSString *headImage = [[NSString alloc] initWithBytes:(request+sizeof(CLUSTERCREATEHRD)+nameLen) length:imageLen encoding:NSUTF8StringEncoding];

    //建立数据库连接
    MysqlDB *mysql = [[MysqlDB alloc] init];
    [mysql connectHost:hostIp connectUser:userName connectPassword:password connectName:dbName];
    //获取当前groupID
    NSString *sqlQuery = [NSString stringWithFormat:@"select max(GroupID) from tbGroup"];
    NSMutableArray *dataResult = [mysql doDataQuery:sqlQuery];
    for (int i = 0 ; i < [dataResult count]; ++i) {
        NSLog(@"%@",[dataResult objectAtIndex:i]);
    }
    
    NSUInteger groupID = 1;
    if([dataResult count] != 0)
    {
        NSArray *temp = [dataResult objectAtIndex:0];
        NSString *maxGroupID = [temp objectAtIndex:0];
        groupID = [maxGroupID integerValue] + 1;
    }
    else 
    {
        NSLog(@"select the max（GroupID) from tbGrop failed when create group");
        NSData *replyData = [[NSData alloc] init ];
        NSData *replyDataWithCmd = [self dataCmd:replyData cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_CREATE_NO];
        [packet.subAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0];        
    }
    
    //插入群信息
    NSString *sqlInsertGroup = [NSString stringWithFormat:@"insert into tbGroup(GroupID,GroupName,GroupCreator,GroupNum,GroupRank,GroupImage) values('%ld','%@','%ld','%ld','1','%@')",groupID,name,userID,count,headImage];
    NSUInteger result = [mysql doDataInsert:sqlInsertGroup];
    if(!result)
    {
        //获取当前id
        NSString *sqlQueryMember = [NSString stringWithFormat:@"select max(ID) from tbGroupMember"];
        NSMutableArray *dataResultMember = [mysql doDataQuery:sqlQueryMember];

        NSUInteger groupMemberID = 1;
        if([dataResultMember count] != 0)
        {
            NSArray *temp = [dataResultMember objectAtIndex:0];
            NSString *maxGroupMemberID = [temp objectAtIndex:0];
            groupMemberID = [maxGroupMemberID integerValue] + 1;
            
            for (NSUInteger i = 0; i < count; ++i) 
            {
                NSUInteger memberID = *((NSUInteger*)(request + sizeof(CLUSTERCREATEHRD) + nameLen + imageLen + i*sizeof(NSUInteger)));
                NSString *sqlInsertGroupMember = [NSString stringWithFormat:@"insert into tbGroupMember(ID,GroupID,MemberID,memberName,MemberTitle) values('%ld','%ld','%ld',' ',' ')",groupMemberID,groupID,memberID];
                // 本应该加入检查
                [mysql doDataInsert:sqlInsertGroupMember];
                ++groupMemberID;
                NSLog(@"%lu",memberID);                
                
//                //添加回复数据包信息
//                NSString *sqlGroupMemberInfo = [NSString stringWithFormat:@"select * from tbUser where UserID = %ld",memberID];
//                NSMutableArray *temp = [mysql doDataQuery:sqlGroupMemberInfo];
//                NSArray *memberInfo = [temp objectAtIndex:0];
//                [memberIDArray addObject:[memberInfo objectAtIndex:COLUNM_OF_GROUPMEMBERID]];
//                [memberNameArray addObject:[memberInfo objectAtIndex:COLUMN_OF_GROUPMEMBERNAME]];
//                [memberImageArray addObject:[memberInfo objectAtIndex:COLUMN_OF_GROUPMEMBERIMAGE]];
            }
        }
        else {
            NSLog(@"select the max(ID) from tbGroupMember failed when create group");
            NSData *replyData = [[NSData alloc] init ];
            NSData *replyDataWithCmd = [self dataCmd:replyData cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_CREATE_NO];
            [packet.subAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0]; 
        }
    }
    else 
    {
        NSLog(@"insert into tbGroup failed when create group");
        NSData *replyData = [[NSData alloc] init ];
        NSData *replyDataWithCmd = [self dataCmd:replyData cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_CREATE_NO];
        [packet.subAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0]; 
    }
    
    
    CLUSTERCREATEREPLYHRD *replyHrd = malloc(sizeof(CLUSTERCREATEREPLYHRD));
    replyHrd->groupID = groupID;
    replyHrd->nameLen = nameLen;
    replyHrd->headImageLen = imageLen;
    
    NSMutableData *replyData = [[NSMutableData alloc] initWithBytes:replyHrd length:sizeof(CLUSTERCREATEREPLYHRD)];
    [replyData appendData:[name dataUsingEncoding:NSUTF8StringEncoding]];
    [replyData appendData:[headImage dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSData *replyDataWithCmd = [self dataCmd:replyData cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_CREATE_YES];
//    [packet.subAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0];

    for (NSUInteger i = 0; i < count; ++i) 
    {
        NSUInteger memberID = *((NSUInteger*)(request + sizeof(CLUSTERCREATEHRD) + nameLen + imageLen + i*sizeof(NSUInteger)));
        @synchronized([MainSocketDelegate connectedSocketsQueue])
        {
            MiniSocket *_sock = [self isBuddyOnline:memberID];   // 判断该好友是否在线
            if (_sock != nil)
            {
                [_sock.miniAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0];
            }
        }
    }
    
    [mysql disconnect];
    
//    NSMutableArray *memberIDArray = [[NSMutableArray alloc] init];
//    NSMutableArray *memberNameArray = [[NSMutableArray alloc] init];
//    NSMutableArray *memberImageArray = [[NSMutableArray alloc] init];
//
//    
//    //发送回复数据包
//    NSData *memberIDData = [NSKeyedArchiver archivedDataWithRootObject:memberIDArray];
//    NSData *memberNameData = [NSKeyedArchiver archivedDataWithRootObject:memberNameArray];
//    NSData *memberImageData = [NSKeyedArchiver archivedDataWithRootObject:memberImageArray];
//    CLUSTERCREATEREPLYHRD *replyHrd = malloc(sizeof(CLUSTERCREATEREPLYHRD));
//    replyHrd->groupID = groupID;
//    replyHrd->count = count;
//    replyHrd->nameLen = nameLen;
//    replyHrd->memberIDLen = [memberIDData length];
//    replyHrd->memberNameLen = [memberNameData length];
//    replyHrd->memberImageLen = [memberImageData length];
//    
//    NSMutableData *replyData = [[NSMutableData alloc] initWithBytes:replyHrd length:sizeof(CLUSTERCREATEREPLYHRD)];
//    [replyData appendData:[name dataUsingEncoding:NSUTF8StringEncoding]];
//    [replyData appendData:memberIDData];
//    [replyData appendData:memberNameData];
//    [replyData appendData:memberImageData];
//    
//    NSData *replyDataWithCmd = [self dataCmd:replyData cmd:CMD_FUN_GROUP subcmd:CMD_GROUP_CREATE_YES];
//    [packet.subAsynSocket writeData:replyDataWithCmd withTimeout:-1 tag:0];
}

// 判断 userId 对应的用户是否在线
- (MiniSocket *)isBuddyOnline:(NSInteger)userId
{
    @synchronized([MainSocketDelegate connectedSocketsQueue])
    {
        // 遍历 connectedSocketQueue，找到该好友的 _sock
        for (MiniSocket *_sock in [MainSocketDelegate connectedSocketsQueue]) 
        {
            if (_sock.userId == userId)
            {
                return _sock;
            }
        }
        return nil;
    }
}
@end
